package com.miniot.base.datasource;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.miniot.base.entity.BaseEntity;
import com.miniot.base.utils.BaseDbInfoUtils;
import com.miniot.business.base.id.IdGenerate;
import org.apache.ibatis.reflection.MetaObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;

public class MyMetaObjectHandler implements MetaObjectHandler {
    private static final Logger log = LoggerFactory.getLogger(com.miniot.business.database.datasource.MyMetaObjectHandler.class);
    private static final String ID_TYPE = "java.lang.String";
    private final IdGenerate<Long> idGenerator;

    public MyMetaObjectHandler(IdGenerate<Long> idGenerator) {
        this.idGenerator = idGenerator;
    }

    public void insertFill(MetaObject metaObject) {
        if (metaObject.getOriginalObject() instanceof BaseEntity) {
            BaseEntity entity = ((BaseEntity) metaObject.getOriginalObject());
            String userId = BaseDbInfoUtils.getCurrentUserId();
            String userName = BaseDbInfoUtils.getCurrentUserName();
            if (entity.getCreateTime() == null) {
                this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
            }
            if (entity.getCreateUser() == null) {
                this.setUserValue(userId, "createUser", metaObject);
                this.setFieldValByName("createUserName", userName, metaObject);
            }
            if (entity.getCompanyId() == null) {
                this.setFieldValByName("companyId", BaseDbInfoUtils.getCurrentCompanyId(), metaObject);
            }
            if (entity.getCompanyName() == null) {
                this.setFieldValByName("companyName", BaseDbInfoUtils.getCurrentCompanyName(), metaObject);
            }
            this.setFieldValByName("delFlag", false, metaObject);
            this.update(metaObject, entity);
        } else {
            for (String item : metaObject.getSetterNames()) {
                if (item.equals("delFlag")) {     //删除标记
                    this.setFieldValByName("delFlag", false, metaObject);
                }
            }
        }
        Long id = this.idGenerator.generate();
        if (ID_TYPE.equals(metaObject.getGetterType("id").getName())) {
            this.setFieldValByName("id", String.valueOf(id), metaObject);
        } else {
            this.setFieldValByName("id", id, metaObject);
        }
    }

    private void update(MetaObject metaObject, BaseEntity entity) {
        if (entity.getUpdateUser() == null || entity.getUpdateUser().equals(0)) {
            if (entity.getUpdateTime() == null) {
                this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
            }
            String userId = BaseDbInfoUtils.getCurrentUserId();
            String userName = BaseDbInfoUtils.getCurrentUserName();
            this.setUserValue(userId, "updateUser", metaObject);
            this.setFieldValByName("updateUserName", userName, metaObject);
        }
    }

    public void updateFill(MetaObject metaObject) {
        log.debug("start update fill ....");
        if (metaObject.getOriginalObject() instanceof BaseEntity) {
            BaseEntity entity = (BaseEntity) metaObject.getOriginalObject();
            this.update(metaObject, entity);
        }
    }

    private void setUserValue(String userId, String keyName, MetaObject metaObject) {
        Class type = metaObject.getGetterType(keyName);
        switch (type.getSimpleName()) {
            case "String":
                this.setFieldValByName(keyName, userId, metaObject);
                break;
            case "Long":
                userId = userId != null ? userId : "-1";
                this.setFieldValByName(keyName, Long.valueOf(userId), metaObject);
                break;
            case "Integer":
                this.setFieldValByName(keyName, Integer.valueOf(userId), metaObject);
                break;
            default:
                throw new RuntimeException("不匹配的数据类型");
        }
    }
}
